#pragma once
#include <time.h>
#include <string>
#include <iostream>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#define PATH "./log"
#define LEVNUM 3


// 打印方式
enum Methon
{
    Screen = 1,
    OneFile,
    MoreFile
};

// 日志级别
enum Level
{
    Debug,
    Warning,
    Fatal
};

using namespace std;
class Log
{
private:
    string _path = PATH;
    Methon _method = Screen; // 打印方式

public:
    void chMethon(Methon methon)
    {
        _method = methon;
    }

    void operator()(Level level, const char *format, ...)
    {
        // 时间
        char *Lev[LEVNUM] = {"Debug", "Warning", "Fatal"};
        time_t t = time(nullptr);
        struct tm *time = localtime(&t);
        char leftbuf[1024] = {0};
        snprintf(leftbuf, sizeof(leftbuf), "[%s]%d-%d-%d %d-%d-%d ", Lev[level], time->tm_year + 1900, time->tm_mon, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec);

        va_list s;
        va_start(s, format);
        char rightbuf[1024];
        vsnprintf(rightbuf, sizeof(rightbuf), format, s);
        va_end(s);

        char buf[2048] = {0};
        snprintf(buf, sizeof(buf), "%s%s\n", leftbuf, rightbuf);
        // 打印
        string filename;
        int fd;
        switch (_method)
        {
        case Screen:
            cout << "----------------------------------" << endl;
            cout << buf << endl;
            break;
        case OneFile:
        filename = _path + "/log.txt";
            fd = open("./log/log.txt", O_WRONLY | O_APPEND | O_CREAT, 0666);
            //buf[sizeof(buf)] = '\0';
            if(fd < 0)
                strerror(errno);
            write(fd, buf, sizeof(buf));
            close(fd);
            break;
        case MoreFile:
            filename = _path;
            filename += "/log.";
            filename += Lev[level];
            fd = open(filename.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666);
            write(fd, buf, sizeof(buf));
            close(fd);
            break;
        default:
            break;
        }
    }
};

Log log;